using SteamTables
using Plots
Thermal Recovery - Part I
Water/Steam Properties
Disclaimer
This blog post is for educational purposes only. Any commercial use of the information provided in this blog post is prohibited. The author is not responsible for any damage or loss caused by the use of the information provided in this blog post.
Introduction
In this post we will use Julia SteamTables.jl
package to estimate water and steam properties. The SteamTables.jl
package is a Julia implementation of IAPWS-IF97 formulation.
Loading required packages
Physical properties of water
The triple point of water is defined as the temperature and pressure at which the solid, liquid and vapor phases coexist in thermodynamic equilibrium. The triple point of water is \(\mathrm T_{3p}\) = 273.16 K
and \(\mathrm P_{3p}\) = 611.657 Pa
. The vapor-liquid critical point of water is defined as the temperature and pressure at which both phases become identical. The critical point of water is \(\mathrm T_{crit}\) = 647.096 K
and \(\mathrm P_{crit}\) = 22.064 MPa
.
Saturation properties
Saturation pressure
Saturation pressure of water can be estimated using the SteamTables.Psat
function. The water phase envelope is generated below from the tripple point \(\mathrm T_{3p}\) = 273.16 K to the critical point \(\mathrm T_{crit}\) = 647.096 K.
= 273.16 # K
T_tripple
= 647.096 # K
T_critical
= unique(vcat(T_tripple, ceil(T_tripple):1.0: floor(T_critical), T_critical))
T
= [Psat(t) for t in T]
p
= plot(T, p,
plt ="Temperature [K]",
xlabel="Pressure [MPa]",
ylabel="Sat. pressure",
label= 3,
lw =:topleft,
legend= 10,
legendfontsize =:box)
framexgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
plot!([T_tripple], [Psat(T_tripple)],
=:scatter,
seriestype="Triple point",
label= 6)
markersize
plot!([T_critical], [Psat(T_critical)],
=:scatter,
seriestype="Critical point",
label= 6) markersize
Saturated density
Saturated liquid and vapor densities are estimated using the SteamTables.SatDensL
and SteamTables.SatDensV
functions.
# saturated liquid density
= [SatDensL(t) for t in T]
ρ
= plot(T, ρ,
plt ="Temperature [K]",
xlabel="Density [kg/m³]",
ylabel="Sat. liquid density",
label= 3,
lw =:topright,
legend= 10,
legendfontsize =:box)
framexgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
# saturated vapor density
= [SatDensV(t) for t in T]
ρ
plot!(T, ρ,
="Sat. vapor density",
label= 3)
lw
plot!([T_critical], [SatDensL(T_critical)],
=:scatter,
seriestype="Critical point",
label= 6) markersize
Saturated enthalpy
Saturated liquid and vapor enthalpies are estimated using the SteamTables.SatHL
and SteamTables.SatHV
functions.
# saturated liquid enthalpy
= [SatHL(t) for t in T] / 1e3
h
= plot(T, h,
plt ="Temperature [K]",
xlabel="Enthalpy [kJ/kg]",
ylabel="Sat. liquid enthalpy",
label= 3,
lw =:bottomright,
legend= 10,
legendfontsize =:box)
framexgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
# saturated vapor enthalpy
= [SatHV(t) for t in T] / 1e3
h
plot!(T, h,
="Sat. vapor enthalpy",
label= 3)
lw
plot!([T_critical], [SatHL(T_critical) / 1e3],
=:scatter,
seriestype="Critical point",
label= 6) markersize
Latent heat of vaporization
The latent heat of vaporization curve is generated using the SteamTables.DeltaHvap
function.
= [DeltaHvap(t) for t in T] / 1e3
h_lv
= plot(T, h_lv,
plt ="Temperature [K]",
xlabel="Latent heat of vaporization [kJ/kg]",
ylabel="Latent heat of vaporization",
label= 3,
lw =:topright,
legend= 10,
legendfontsize =:box)
framexgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
plot!([T_critical], [h_lv[end]],
=:scatter,
seriestype="Critical point",
label= 6) markersize
A list of all the available functions can be found in the SteamTables.jl documentation.
Wet steam properties
The physical properties of a wet steam mixture (saturated vapor and liquid) is defined by the following equations:
\[ \begin{align} p &= p_{sat}(T) \\[10pt] h &= \left(1 - x \right) h_{sat}^{l}(T) + x \left( h_{sat}^{v}(T) \right) \\[10pt] s &= \left(1 - x \right) s_{sat}^{l}(T) + x \left( s_{sat}^{v}(T) \right) \\[10pt] \rho &= \left(1 - x \right) \rho_{sat}^{l}(T) + x \left( \rho_{sat}^{v}(T) \right) \end{align} \]
where steam quality \(x\) is in weight fraction and defined as:
\[ x = \frac{mass_{vapor}}{mass_{total}} \]
The saturated enthalpy curves are generated below for a wet steam at several steam qualities.
= [0.0, 0.25, 0.50, 0.75, 1.0]
x
= [(1 - x[1]) * SatHL(t) + x[1] * SatHV(t) for t in T] / 1e3
h
= plot(h, T,
plt = "Enthalpy [kJ/kg]",
xlabel = "Temperature [K]",
ylabel = "x = $(x[1])",
label = 3,
lw =:topleft,
legend= 10,
legendfontsize =:box,
frame= "Enthalpy plot for wet steam")
title xgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
for i in 2:length(x)
= [(1 - x[i]) * SatHL(t) + x[i] * SatHV(t) for t in T] / 1e3
h plot!(h, T,
= "x = $(x[i])",
label = 3)
lw end
plot!([SatHL(T_critical) / 1e3], [T_critical],
=:scatter,
seriestype="Critical point",
label= 6) markersize
Subcooled liquid and superheated vapor properties
SteamTables.jl
also provides functions for calculating the properties of subcooled liquid and superheated vapor. The following examples shows the application of specific functions in predicting water propertis over a wide range of temperature and pressure.
Specific properties
The specific properties of water are calculated using the SteamTables.SpecificH
, SteamTables.SpecificS
, SteamTables.SpecificV
, and SteamTables.SpecificCP
functions. The specific enthalpy curve is generated below from 273.16 K to 747.096 K at a constant pressure of 10 MPa.
= vcat(274:1.0:800) # K
T = 10 # MPa
P
= zeros(length(T))
h = zeros(length(T))
s = zeros(length(T))
v = zeros(length(T))
Cp
for i in 1:length(T)
= SpecificH(P, T[i])
h[i] = SpecificS(P, T[i])
s[i] = SpecificV(P, T[i])
v[i] = SpecificCP(P, T[i])
Cp[i] end
The figure below shows the change in specific enthalpy over a wide range of temperatures at a constant pressure of 10 MPa.
= plot(T, h,
plt ="Temperature [K]",
xlabel="Enthalpy [kJ/kg]",
ylabel="Specific enthalpy",
label= 3,
lw =:bottomright,
legend= 10,
legendfontsize =:box)
framexgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
A similar plot can be generated for the specific volume curve.
= plot(T, v,
plt ="Temperature [K]",
xlabel="Volume [m3/kg]",
ylabel="Specific volume",
label= 3,
lw =:bottomright,
legend= 10,
legendfontsize =:box)
framexgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
There are other functions for calculating the specific properties of water. A list of all the available functions can be found in the SteamTables.jl documentation.
Pressure-Volume diagram construction
The pressure-volume diagram of water can be constructed using the SteamTables.SatDensL
, SteamTables.SatDensV
, and SteamTables.SpecificV
functions. Firstly, the saturated liquid and vapor volume curves are generated from the triple point to the critical point. Then, the specific volume of water is calculated at several constant temperatures over a wide pressure range.
= 273.16 # K
T_tripple
= 647.096 # K
T_critical
= unique(vcat(T_tripple, ceil(T_tripple):0.1: floor(T_critical), T_critical))
T
= [Psat(t) for t in T]
p
= 1.0 ./ [SatDensL(t) for t in T]
ν_l
= 1.0 ./ [SatDensV(t) for t in T]
ν_v
= [1e-3, 1e-2, 1e-1, 1e0, 1e1, 1e2]
x_log_range = [1e-3, 1e-2, 1e-1, 1e0, 1e1]
y_log_range
= plot(ν_l, p,
plt = "Specific volume [m3/kg]",
xlabel = "Pressure [MPa]",
ylabel = :none,
label =:log10,
xscale=(x_log_range, x_log_range),
xticks=:log10,
yscale=(y_log_range, y_log_range),
yticks= 3,
lw = :red,
linecolor =:topright,
legend= 10,
legendfontsize =:box,
frame= "Pressure-Volume diagram of water")
title xgrid!(:on, :cadetblue, 2, :dashdot, 0.4)
ygrid!(:on, :cadetblue, 2, :dashdot, 0.4)
plot!(ν_v, p,
= 3,
lw = :red,
linecolor = :none)
label
plot!([1.0 / SatDensL(T_critical)], [Psat(T_critical)],
=:scatter,
seriestype="Critical point",
label= 6)
markersize
# construct subcooled liquid and superheated vapor curves
= vcat(350:100:550)
T_ = 0.001:0.001:40.0
p_
for i in 1:length(T_)
= [SpecificV(p, T_[i]) for p in p_]
ν_ plot!(ν_, p_,
= 3,
lw =:dash,
line = "T = $(T_[i])")
label end
display(plt)